home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 2.toast / pc / sample code / interapplication comm / makestartupaliastome / makestartupaliastome.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-23  |  11.4 KB  |  295 lines

  1. /*
  2.     File: MakeStartupAliasToMe.c
  3.     
  4.     Description:
  5.         This small application illustrating how to launch an AppleScript
  6.     and send a list of files to it for processing.  This a simple way
  7.     for your application to access the powerful high level facilities
  8.     provided by AppleScript. 
  9.  
  10.     Copyright:
  11.         © Copyright 2000 Apple Computer, Inc. All rights reserved.
  12.     
  13.     Disclaimer:
  14.         IMPORTANT:  This Apple software is supplied to you by Apple Computer, Inc.
  15.         ("Apple") in consideration of your agreement to the following terms, and your
  16.         use, installation, modification or redistribution of this Apple software
  17.         constitutes acceptance of these terms.  If you do not agree with these terms,
  18.         please do not use, install, modify or redistribute this Apple software.
  19.  
  20.         In consideration of your agreement to abide by the following terms, and subject
  21.         to these terms, Apple grants you a personal, non-exclusive license, under Apple’s
  22.         copyrights in this original Apple software (the "Apple Software"), to use,
  23.         reproduce, modify and redistribute the Apple Software, with or without
  24.         modifications, in source and/or binary forms; provided that if you redistribute
  25.         the Apple Software in its entirety and without modifications, you must retain
  26.         this notice and the following text and disclaimers in all such redistributions of
  27.         the Apple Software.  Neither the name, trademarks, service marks or logos of
  28.         Apple Computer, Inc. may be used to endorse or promote products derived from the
  29.         Apple Software without specific prior written permission from Apple.  Except as
  30.         expressly stated in this notice, no other rights or licenses, express or implied,
  31.         are granted by Apple herein, including but not limited to any patent rights that
  32.         may be infringed by your derivative works or by other works in which the Apple
  33.         Software may be incorporated.
  34.  
  35.         The Apple Software is provided by Apple on an "AS IS" basis.  APPLE MAKES NO
  36.         WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
  37.         WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  38.         PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
  39.         COMBINATION WITH YOUR PRODUCTS.
  40.  
  41.         IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
  42.         CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  43.         GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  44.         ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
  45.         OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
  46.         (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
  47.         ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  48.  
  49.     Change History (most recent first):
  50.         Monday, March 27, 2000 -- created
  51. */
  52.  
  53.  
  54. #include <Types.h>
  55. #include <QuickDraw.h>
  56. #include <Processes.h>
  57. #include <Aliases.h>
  58. #include <Sound.h>
  59. #include <PLStringFuncs.h>
  60. #include <Resources.h>
  61. #include <Files.h>
  62. #include <Folders.h>
  63. #include <TextUtils.h>
  64.  
  65. #include "debugf.h"
  66.  
  67.  
  68.     /* kScriptNameSTRID is the resource ID number for a resource
  69.     of type 'STR ' stored in the application's resource file.  This resource
  70.     contains the name of the AppleScript we will launch to create the alias */
  71. #define kScriptNameSTRID 128
  72.  
  73.     /* kScriptLocationsStringListID contains the resource ID of a string
  74.     list resource (type 'STR#') stored in the application's resource fork.
  75.     The strings stored in this resource list the names of folders inside
  76.     of the same folder where the application resides where the program
  77.     will search for the script named in the 'STR ' resource described above. */
  78. #define kScriptLocationsStringListID 128
  79.  
  80.     /* kLaunchFailedAlertID is the resource ID of the alert displayed when
  81.     a problem occurs either finding or launching the script.  It does not
  82.     display errors reported by the script itself--it is up to the script
  83.     to report those errors. */
  84. #define kLaunchFailedAlertID 128
  85.  
  86.  
  87.  
  88.     /* FindCurrentApplication locates the current application's
  89.     file and returns a reference to it in the file specification
  90.     record provided as a parameter. */
  91. static OSStatus FindCurrentApplication(FSSpec *spec) {
  92.     OSStatus err;
  93.     ProcessSerialNumber PSN;
  94.     ProcessInfoRec info;
  95.         /* get the current process ID */
  96.     err = GetCurrentProcess(&PSN);
  97.     if (err != noErr) return err;
  98.         /* get the current process location */
  99.     BlockZero(&info, sizeof(info));
  100.     info.processInfoLength = sizeof(ProcessInfoRec);
  101.     info.processAppSpec = spec;
  102.     err = GetProcessInformation(&PSN, &info);
  103.     if (err != noErr) return err;
  104.         /* done */
  105.     return noErr;
  106. }
  107.  
  108.  
  109.     /* LaunchScriptWithFiles launches the script referenced by the *asDroplet
  110.     file specification record and sends the list of files referenced by fileList to
  111.     it for processing.  For this routine to work, the script must:
  112.     (a) be saved as an applet,
  113.     (b) the applet's script must contain a "on open ..." block for
  114.         processing the list of files sent to it by this routine. 
  115.     (c) display any error alerts should incident occur.
  116.     LaunchScriptWithFiles will report any errors that occur while constructing
  117.     the list of files to send to the script and while launching the script, but
  118.     it will not report any errors that may occur while the script is being
  119.     processed.  As a result, if the script encounters any errors, it should
  120.     display an appropriate alert describing the problem that occured.  */    
  121. static OSStatus LaunchScriptWithFiles(FSSpec *asDroplet, FSSpec *fileList, long fileCount) {
  122.     OSErr err;
  123.     AEAddressDesc appParamsAETargetAddr;
  124.     AEDescList targetFileListDesc;
  125.     AEDesc appParamsDesc;
  126.     AppleEvent appParamsAE;
  127.     AliasHandle targetFileAlias;
  128.     FInfo fndrInfo;
  129.     AppParametersPtr appParams;
  130.     LaunchParamBlockRec launchParam;
  131.     long bytecount, index;
  132.     FSSpec *nthFile;
  133.     
  134.         /* initialize our records to NULL descriptors */
  135.     AECreateDesc(typeNull, NULL, 0, &appParamsAETargetAddr);
  136.     AECreateDesc(typeNull, NULL, 0, &targetFileListDesc);
  137.     AECreateDesc(typeNull, NULL, 0, &appParamsAE);
  138.     AECreateDesc(typeNull, NULL, 0, &appParamsDesc);
  139.     targetFileAlias = NULL;
  140.     appParams = NULL;
  141.         
  142.         /* create an open documents Apple event */
  143.     err = FSpGetFInfo(asDroplet, &fndrInfo);
  144.     if (err != noErr) goto bail;
  145.     err = AECreateDesc(typeApplSignature, (Ptr)&fndrInfo.fdCreator,
  146.         sizeof(OSType), &appParamsAETargetAddr);
  147.     if (err != noErr) goto bail;
  148.     err = AECreateAppleEvent(kCoreEventClass, kAEOpenDocuments,
  149.         &appParamsAETargetAddr, kAutoGenerateReturnID, kAnyTransactionID, &appParamsAE);
  150.     if (err != noErr) goto bail;
  151.         
  152.         /* create a list of files to send to the droplet */
  153.     err = AECreateList(NULL, 0, false, &targetFileListDesc);
  154.     if (err != noErr) goto bail;
  155.     for (nthFile = fileList, index=0; index < fileCount; index++, nthFile++) {
  156.         err = NewAlias(NULL, nthFile, &targetFileAlias);
  157.         if (err != noErr) goto bail;
  158.         HLock((Handle) targetFileAlias);
  159.         err = AEPutPtr(&targetFileListDesc, index + 1, typeAlias,
  160.             (Ptr) (*targetFileAlias), GetHandleSize((Handle) targetFileAlias));
  161.         DisposeHandle((Handle) targetFileAlias);
  162.         targetFileAlias = NULL;
  163.         if (err != noErr) goto bail;
  164.     }
  165.     
  166.         /* add the file list to the open documents apple event */
  167.     err = AEPutParamDesc(&appParamsAE, keyDirectObject, &targetFileListDesc);
  168.     if (err != noErr) goto bail;
  169.     
  170.         /* coerce the apple event to app parameters */
  171.     err = AECoerceDesc(&appParamsAE, typeAppParameters, &appParamsDesc);
  172.     if (err != noErr) goto bail;
  173.     bytecount = AEGetDescDataSize(&appParamsDesc);
  174.     appParams = (AppParametersPtr) NewPtr(bytecount);
  175.     if (appParams == NULL) { err = memFullErr; goto bail; }
  176.     err = AEGetDescData(&appParamsDesc, appParams, bytecount);
  177.     if (err != noErr) goto bail;
  178.     
  179.         /* launch the application */
  180.     BlockZero(&launchParam, sizeof(launchParam));
  181.     launchParam.launchBlockID = extendedBlock;
  182.     launchParam.launchEPBLength = extendedBlockLen;
  183.     launchParam.launchFileFlags = 0;
  184.     launchParam.launchControlFlags = launchContinue + launchNoFileFlags;
  185.     launchParam.launchAppSpec = asDroplet;
  186.     launchParam.launchAppParameters = appParams;
  187.     err = LaunchApplication(&launchParam);
  188.  
  189. bail:
  190.     if (appParams != NULL) DisposePtr((Ptr) appParams);
  191.     if (targetFileAlias != NULL) DisposeHandle((Handle) targetFileAlias);
  192.     AEDisposeDesc(&appParamsAE);
  193.     AEDisposeDesc(&appParamsAETargetAddr);
  194.     AEDisposeDesc(&appParamsDesc);
  195.     AEDisposeDesc(&targetFileListDesc);
  196.     return err;
  197. }
  198.  
  199.  
  200.     /* LocateExecutableScriptFile locates the AppleScript named scriptName.
  201.     If appRelPathsID is not zero, then LocateExecutableScriptFile will search
  202.     the folders named in the string list resource with that ID inside of the
  203.     application's directory before searching the system's script folder.  If
  204.     a script with a matching name is found, then a reference will be returned
  205.     in the *targetScript file specification record. */
  206. static OSStatus LocateExecutableScriptFile(StringPtr scriptName, short appRelPathsID, FSSpec *targetScript) {
  207.     OSStatus err;
  208.     ProcessSerialNumber PSN;
  209.     ProcessInfoRec info;
  210.     short **paths, i, n, vRefNum;
  211.     long dirID;
  212.     FSSpec appSpec, theScript;
  213.     Str255 theName;
  214.     CInfoPBRec cat;
  215.         /* locate the application's folder using our custom paths*/
  216.     if (appRelPathsID != 0) {
  217.         paths = (short **) GetResource('STR#', appRelPathsID);
  218.         if (paths == NULL) { err = resNotFound; return err; }
  219.         n = **paths;
  220.             /* find the application's location */
  221.         if ((err = GetCurrentProcess(&PSN)) != noErr) return err;
  222.         BlockZero(&info, sizeof(info));
  223.         info.processInfoLength = sizeof(ProcessInfoRec);
  224.         info.processAppSpec = &appSpec;
  225.         if ((err = GetProcessInformation(&PSN, &info)) != noErr) return err;
  226.             /* search application relative paths */
  227.         for (i=1; i<= n; i++) {
  228.             GetIndString(theName, appRelPathsID, i);
  229.             BlockZero(&cat, sizeof(cat));
  230.             cat.hFileInfo.ioNamePtr = theName;
  231.             cat.hFileInfo.ioVRefNum = appSpec.vRefNum;
  232.             cat.hFileInfo.ioDirID = appSpec.parID;
  233.             if (PBGetCatInfoSync(&cat) == noErr) 
  234.                 if ((cat.hFileInfo.ioFlAttrib & 16) != 0)
  235.                     if (FSMakeFSSpec(appSpec.vRefNum, cat.hFileInfo.ioDirID, scriptName, &theScript) == noErr) {
  236.                         *targetScript = theScript;
  237.                         return noErr;
  238.                     }
  239.         }
  240.     }
  241.         /* not there, use the scripts folder */
  242.     if (FindFolder(kOnSystemDisk, kScriptsFolderType, false, &vRefNum, &dirID) == noErr) {
  243.         if (FSMakeFSSpec(vRefNum, dirID, scriptName, &theScript) == noErr) {
  244.             *targetScript = theScript;
  245.             return noErr;
  246.         }
  247.     }
  248.         /* we failed */
  249.     return fnfErr;
  250. }
  251.  
  252.  
  253.  
  254.  
  255.  
  256. int main(void) {
  257.     FSSpec theApp;
  258.     FSSpec theScript;
  259.     OSStatus err;
  260.     Str255 errStr;
  261.     Str255 scriptName;
  262.     StringHandle scriptNameHandle;
  263.     
  264.         /* get the name of the script */
  265.     scriptNameHandle = GetString(kScriptNameSTRID);
  266.     if (scriptNameHandle == NULL) {
  267.         PLstrcpy(scriptName, "\punknown script");
  268.         err = resNotFound;
  269.         goto bail;
  270.     } else {
  271.         HLock((Handle) scriptNameHandle);
  272.         PLstrcpy(scriptName, *scriptNameHandle);
  273.         HUnlock((Handle) scriptNameHandle);
  274.     }
  275.     
  276.         /* locate the script file */
  277.     err = LocateExecutableScriptFile(scriptName, kScriptLocationsStringListID, &theScript);
  278.     if (err != noErr) goto bail;
  279.  
  280.         /* create a reference to our application */
  281.     err = FindCurrentApplication(&theApp);
  282.     if (err != noErr) goto bail;
  283.  
  284.         /* launch the script providing our application reference as a parameter */
  285.     err = LaunchScriptWithFiles(&theScript, &theApp, 1);
  286.     if (err != noErr) goto bail;
  287.  
  288.     return 0;
  289. bail:
  290.     InitCursor();
  291.     NumToString(err, errStr);
  292.     ParamText(scriptName, errStr, NULL, NULL);
  293.     StopAlert(kLaunchFailedAlertID, NULL);
  294.     return 1;
  295. }